package com.dhnsoft.shortLink.stream;

import org.junit.jupiter.api.Test;

import java.util.*;
import java.util.stream.Collectors;

public class StreamDemo {

    public static void main(String[] args) {
//        List<Author> authors = getAuthors();
//        authors.stream()
//                .distinct()
//                .filter(author -> author.getAge()<18)
//                .forEach(author -> System.out.println(author));

//        Integer[] arr = {1,2,2,3,4};
//        Arrays.stream(arr).distinct().forEach(item-> System.out.println(item));


//        Map<String, Integer> map = new HashMap<>();
//        map.put("蜡笔小新", 18);
//        map.put("黑子", 15);
//        map.put("日向雏田", 17);
//        map.entrySet().stream()
//                .filter(stringIntegerEntry -> stringIntegerEntry.getValue()>15)
//                .forEach(stringIntegerEntry -> System.out.println(stringIntegerEntry.getKey()+":"+stringIntegerEntry.getValue()));

    }

    /**
     * filter
     * */
    @Test
    public void test01(){
        List<Author> authors = getAuthors();
        authors.stream().filter(item->item.getName().length()>2)
                .forEach(item-> System.out.println(item));
    }


    /**
     * map
     * */
    @Test
    public void test02(){
        getAuthors().stream()
                .map(author -> author.getName())
                .forEach(item-> System.out.println(item));
    }

    /**
     * sort
     * */
    @Test
    public void test03(){
        getAuthors().stream()
                .distinct()
                .sorted((o1, o2) -> o1.getAge()-o2.getAge())
                .forEach(item-> System.out.println(item));
    }

    /**
     * limit
     * */
    @Test
    public void test04(){
        getAuthors().stream()
                .sorted((o1, o2) -> o2.getAge()-o1.getAge())
                .limit(2)
                .forEach(System.out::println);
    }

    /**
     * skip
     * */
    @Test
    public void test05(){
        getAuthors().stream()
                .distinct()
                .sorted()
                .skip(1)
                .forEach(item-> System.out.println(item));
    }

    /**
     * flatMap
     * 打印所有书籍的名字，要求对重复的元素进行去重。
     * */
    @Test
    public void test06(){
        getAuthors()
                .stream()
                .flatMap(item->item.getBooks().stream())
                .distinct()
                .forEach(item-> System.out.println(item));
    }

    /**
     * flatMap
     * 案例二：打印现有数据的所有分类，要求对分类进行去重。不能出现这种格式：哲学,爱情，要将它们拆开输出。
     * */
    @Test
    public void test07(){
        getAuthors()
                .stream()
                .flatMap(item->item.getBooks().stream().flatMap(book-> Arrays.stream(book.getCategory().split(","))))
                .distinct()
                .forEach(item-> System.out.println(item));
    }

    /**
     * max&min
     * 分别获取这些作家所出书籍的最高分和最低分
     * */
    @Test
    public void test08(){
        Optional<Integer> max = getAuthors().stream()
                .flatMap(item -> item.getBooks().stream())
                .map(item -> item.getScore())
                .max((o1, o2) -> o1 - o2);
        System.out.println(max.get());
    }

    /**
     * list
     * 获取一个存放所有作者名字的list集合
     * */
    @Test
    public void test09(){
        List<String> list = getAuthors().stream()
                .map(item -> item.getName())
                .collect(Collectors.toList());
    }

    /**
     * set
     * 获取一个存放所有作者的数书的set集合
     * */
    @Test
    public void test10(){
        Set<String> collect = getAuthors().stream()
                .flatMap(item -> item.getBooks().stream())
                .map(item -> item.getName())
                .collect(Collectors.toSet());
    }

    /**
     * map
     * //获取一个Map集合，map的key为作者名，value为List<Book>
     * */
    @Test
    public void test11(){
        Map<String, List<Book>> collect = getAuthors().stream()
                .distinct()
                .collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
        System.out.println(collect);
    }

    /**
     * anyMatch
     *判断是否有作家年龄在18以上
     * */
    @Test
    public void test12(){
        getAuthors().stream()
                .anyMatch(item->item.getAge()>18);
    }

    /**
     * 判断是否所有作家年龄在18以上
     * allMatch
     * */
    @Test
    public void test13(){
        getAuthors().stream()
                .allMatch(item->item.getAge()>18);
    }

    /**
     * findAll
     * 获取任意一个年龄大于18的作家，如果存在就输出他的名字
     * */

    @Test
    public void test14(){
        getAuthors().stream()
                .filter(item->item.getAge()>18)
                .findAny()
                .ifPresent(item-> System.out.println(item.getName()));
    }

    /**
     * findFirst
     * 获取一个年龄最小的作家，并输出他的姓名
     * */
    @Test
    public void test15(){
        System.out.println(getAuthors().stream()
                .sorted((o1, o2) -> o1.getAge() - o2.getAge())
                .findFirst());
    }

    /**
     * reduce
     * 使用reduce求所有作者年龄的和
     * */
    @Test
    public void test16(){
        Integer age = getAuthors().stream()
                .map(item -> item.getAge())
                .reduce(0, (integer, integer2) -> integer + integer2);
        System.out.println(age);
    }
    /**
     * reduce
     * 使用reduce求所有作者年龄的最大值
     * */
    @Test
    public void test17(){
        Integer age = getAuthors().stream()
                .map(item -> item.getAge())
                .reduce(Integer.MIN_VALUE, (result, element) -> result>element?result:element) ;
        System.out.println(age);
    }
    /**
     * reduce一个参数
     * 使用reduce求所有作者年龄的最小值
     * */
    @Test
    public void test18(){
        Optional<Integer> age = getAuthors().stream()
                .map(item -> item.getAge())
                .reduce((result, element) -> result>element?element:result);
        System.out.println(age.get());
    }





    private List<Author> getAuthors() {
        Author  author = new Author(1L, "蒙多", 17, "一个祖安人", null);
        Author author2 = new Author(2L, "亚拉索", 18, "艾欧尼亚", null);
        Author author3 = new Author(3L, "易大师", 19, "黑色玫瑰", null);
        Author author4 = new Author(3L, "易大师", 19, "黑色玫瑰", null);

        List<Book> book1 = new ArrayList<>();
        List<Book> book2 = new ArrayList<>();
        List<Book> book3 = new ArrayList<>();
        List<Book> book4 = new ArrayList<>();

        book1.add(new Book(1L,"*","哲学,爱情", 80, "*"));
        book1.add(new Book(2L,"**","爱情,个人成长", 80, "**"));

        book2.add(new Book(3L,"***","爱情,传记", 70, "***"));
        book2.add(new Book(3L,"****","个人成长,传记", 70, "****"));
        book2.add(new Book(4L,"*****","哲学", 70, "*****"));

        book3.add(new Book(5L,"******","个人成长", 60, "******"));
        book3.add(new Book(6L,"*******","传记", 60, "*******"));
        book3.add(new Book(6L,"********","爱情", 60, "********"));

        book4.add(new Book(5L,"******","个人成长", 60, "******"));
        book4.add(new Book(6L,"*******","个人成长,传记,爱情", 60, "*******"));
        book4.add(new Book(6L,"********","哲学,爱情,个人成长", 60, "********"));


        author.setBooks(book1);
        author2.setBooks(book2);
        author3.setBooks(book3);
        author4.setBooks(book4);

        List<Author> authors = new ArrayList<>(Arrays.asList(author,author2,author3,author4));
        return authors;
    }
}
